home *** CD-ROM | disk | FTP | other *** search
- /* tr - like unix tr
-
- ** THIS PROGRAM MUST BE COMPILED WITH THE EXTENDED PREPROCESSOR
- ** IE: cc TR -p
-
- by jim mckim
-
- this program may be used in several ways. By example:
-
- tr A-Z a-z <input >output
- will convert upper case to lower case
-
- tr -c !-~ ? <input >output
- will convert unprintable characters to question marks
-
- tr -cs !-~ \40 <input >output
- will convert unprintable characters to spaces and squeeze out extra spaces
-
- tr -d \177-\377 <input
- will remove all characters whose eighth bit is set
-
- comments about this can reach me via BIX (jmckim)
- or telephone (216 835 3845)
- or USPS
- (Jim McKim
- 30224 Wolf Rd.
- Bay Village, OH 44140)
-
- (i gladly accept bug reports; bug fixes will make me ecstatic)
-
- Compile command: cc tr -fop
- */
-
- #include <stdio.h>
- #include <file.h>
-
- #define TTSIZE 257
- #define isodigit(c) ((c)>='0' && (c)<='7')
-
- TellHow()
- {
- fputs("usage: tr [-flags] string1 string2 <input >output\n", stderr);
- fputs("where flags are:\n",stderr);
- fputs("c compliment string1 (e.g. all NOT in string1)\n",stderr);
- fputs("d delete if in string1\n",stderr);
- fputs("s squeeze out duplicates if in string2\n",stderr);
- fputs("r raw (no cr/lf conversion) (MSDOS only)\n",stderr);
- exit(-1);
- }
-
- Interpret(input,output)
- char *input, *output;
- {
- int startc, endc;
- int i;
- int range_flag; /* true when '-' has been seen */
- int got_next; /* true when char after '-' has been seen */
-
- *output = range_flag = got_next = 0;
- while (*input)
- {
- if (*input == '\\')
- {
- ++input;
- if (isodigit(*input))
- {
- /* got an octal constant */
- i = *input - '0';
- if (isodigit(*(input+1)))
- {
- i = i*8 + *++input - '0';
- if (isodigit(*(input+1)))
- i = i*8 + *++input - '0';
- }
- *output++ = i;
- if (range_flag)
- got_next = 1;
- }
- else
- {
- /* got a \c type character */
- *output++ = *input;
- if (range_flag)
- got_next = 1;
- }
- }
- else if (*input == '-')
- {
- /* got a range */
- range_flag = 1;
- }
- else
- {
- /* got a normal character */
- *output++ = *input;
- if (range_flag)
- got_next = 1;
- }
-
- ++input;
-
- if (range_flag && got_next)
- {
- startc = *(output-2);
- endc = *(output-1);
- output -= 2;
- for (i=startc; i<=endc; ++i)
- *output++ = i;
- range_flag = got_next = 0;
- }
- } /* end while */
- *output = '\0';
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- char incode[TTSIZE], outcode[TTSIZE], trtbl[TTSIZE];
- char inset[TTSIZE];
- char inch, outch, old_outch;
- int i, j, iarg;
- char c_flag, d_flag, s_flag;
- char *iap;
-
- iarg = 1;
- c_flag = d_flag = s_flag = 0;
-
- /* get the switches */
- while ((iarg <= argc) && (*argv[iarg] == '-'))
- {
- iap = argv[iarg++] + 1; /* point past '-' */
- while (*iap)
- switch (*iap++)
- {
- case 'c': /* Compliment string */
- c_flag = 1;
- break;
- case 'd': /* Delete */
- d_flag = 1;
- break;
- case 's': /* Squeeze out duplicates */
- s_flag = 1;
- break;
- case 'r': /* Raw I/O mode */
- *stdin |= F_BINARY;
- *stdout |= F_BINARY;
- break;
- default:
- TellHow();
- }
- }
-
- if (iarg+1 >= argc)
- {
- TellHow();
- }
-
- for (i=0; i<TTSIZE; ++i)
- {
- trtbl[i] = i;
- inset[i] = '\0';
- incode[i] = '\0';
- outcode[i] = '\0';
- }
-
- Interpret(argv[iarg++],incode);
- Interpret(argv[iarg],outcode);
-
- i = 0;
- j = 0;
- while (incode[i])
- {
- inset[incode[i]] = 1;
- if (c_flag == 0)
- {
- trtbl[incode[i]] = outcode[j];
- /* if next is null, dup last */
- if (outcode[j+1])
- ++j;
- }
- ++i;
- }
-
- if (c_flag == 1)
- {
- j = 0;
- for (i=0; i<TTSIZE; ++i)
- {
- if (inset[i] == 0)
- {
- inset[i] = 1;
- trtbl[i] = outcode[j];
- if (outcode[j+1])
- ++j;
- }
- else
- {
- inset[i] = 0;
- trtbl[i] = i;
- }
- }
- }
-
- /* To speed up processsing, switch stdio streams to buffered */
- stdin = setbuf(stdin, 1024);
- stdout = setbuf(stdout, 1024);
-
- outch = '\0';
- while ((inch=getc(stdin)) != EOF)
- {
- old_outch = outch;
- outch = trtbl[inch];
- if (d_flag)
- if (inset[inch])
- continue;
- if (s_flag)
- if (inset[inch])
- if (old_outch == outch)
- continue;
- putc(outch, stdout);
- }
-
- fflush(stdout); /* Insure output buffer is written */
- }
-